package client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.UnknownHostException;
import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import ssl.SecureSocket;
import ssl.SecureSocketClient;

public class ClientSSLConnection {

	public ClientSSLResult register(String host, String username, KeyPair cPubKey) {
		SSLSocket remoteSocket;
		System.setProperty("javax.net.ssl.trustStore", "myKeystore"); // Truststore
																		// File
																		// in
																		// den
																		// Umgebungsvariablen
																		// festlegen
		System.setProperty("javax.net.ssl.trustStorePassword", "123456"); // Truststore
																			// Passwort
																			// in
																			// den
																			// Umgebungsvariablen
																			// festlegen
		try {
			SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
					.getDefault(); // Erzeugt eine SSLSocketFactory mit
									// Standartkonfiguration
			remoteSocket = (SSLSocket) factory.createSocket(host, 9999); // SSLSocket
																			// erstellen
																			// (und
																			// zu
																			// Server
																			// verbinden)
			OutputStream out = remoteSocket.getOutputStream();
			OutputStreamWriter swout = new OutputStreamWriter(out);
			BufferedWriter bout = new BufferedWriter(swout);

			// Verbindung ist über SSL vertrauenswürdig gesichert,
			// also keine man-in-the-middle möglich.
			// Daher ist Gegenstelle vertrauenswürdig,
			// nur vor abhören muss abgesichert werden.
			// Dies übernimmt der SSL Socket (TODO)

			// Während dieser Vertrauenswürdigen Phase werden
			// die Public Keys ausgetauscht, um sicherzustellen,
			// das bei späterer Datenübertragung auch wirklich
			// kein man-in-the-middle möglich ist.
			String[] cPubKeyString = SecureSocketClient.generateStringRSAPublicKey((RSAPublicKey)cPubKey.getPublic());
			String antwort = "register " + username + " " + cPubKeyString[0] + " " + cPubKeyString[1] + "\n";
			bout.write(antwort);
			bout.flush();

			InputStream in = remoteSocket.getInputStream();
			InputStreamReader din = new InputStreamReader(in);
			BufferedReader bin = new BufferedReader(din);

			String command = bin.readLine();

			String[] strings = command.split(" ");

			if (strings.length == 4) {
				String befehl = strings[0];

				if (befehl.equals("register_ok")) {
					String pw = strings[1];
					String serverPublicKeyMod = strings[2];
					String serverPublicKeyExp = strings[3];

					String[] stringKeypair = { serverPublicKeyMod,
							serverPublicKeyExp };
					KeyPair serverPublicKey = new KeyPair(SecureSocket
							.generateRSAPublicKey(stringKeypair), null);

					ClientSSLResult result = new ClientSSLResult(pw,
							serverPublicKey);
					remoteSocket.close();
					return result;
				}
			}

			remoteSocket.close();
			return null;

		} catch (UnknownHostException e) {
			System.out.println("Konnte Zielserver nicht erreichen");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("IO Exception??");
			e.printStackTrace();
		}
		return null;
	}
}
